﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GmFamilyDatabase.h"
#include <memory>

namespace gfam
{
    class IFamilyDatabase;
    class IFamilyDataTable;
    class IFamilyDataTableList;
    class IFamilyDataColumn;
    class IFamilyDataRow;
    class IFamilyDataColumnList;
    class IFamilyDataRowList;


    /// \brief 数据类型
    enum class FamilyDataType : int16_t
    {
        Null   = 0, 
        Int32  = 1,
        Int64  = 2,
        Double = 3,
        String = 4
    };


    /// \brief 数据库工厂接口
    class GM_FAMILY_DATABASE_EXPORT FamilyDatabaseFactory
    {
    public:
        /// \brief 创建并打开数据库
        /// \param dbPath 数据库路径
        /// \return 返回数据库指针
        static std::shared_ptr<IFamilyDatabase> CreateDatabase(const std::wstring& dbPath);
    };


    /// \brief 数据库接口
    class IFamilyDatabase
    {
    public:
        /// \brief 关闭数据库
        virtual void Close() = 0;

    /// \brief 数据表操作相关接口
    public:
        /// \brief 获取数据表
        /// \return 返回数据表集合
        virtual std::shared_ptr<IFamilyDataTableList> GetTables() const = 0;

        /// \brief 查找数据表
        /// \param tableName 表名称
        /// \return 返回数据表对象
        virtual std::shared_ptr<IFamilyDataTable> FindTable(const std::wstring& tableName) const = 0;

        /// \brief 创建新数据表
        /// \return 返回新创建的数据表
        virtual std::shared_ptr<IFamilyDataTable> NewTable() = 0;

        /// \brief 添加数据表
        /// \param newTable 数据表
        virtual void AddTable(const std::shared_ptr<IFamilyDataTable> newTable) = 0;

        /// \brief 删除数据表
        /// \param tableName 数据表名
        virtual void RemoveTable(const std::wstring& tableName) = 0;

    /// \brief 数据库事务相关接口
    public:
        /// \brief 开启事务
        /// \return 返回是否成功开启事务，true为成功开启事务，false为失败
        virtual bool Transaction() = 0;

        /// \brief 提交事务
        /// \return 返回是否成功提交事务，true为成功提交事务，false为失败
        virtual bool Commit() = 0;

        /// \brief 回滚事务
        /// \return 返回是否成功回滚事务，true为成功回滚事务，false为失败
        virtual bool Rollback() = 0;

        /// \brief 是否在事务中
        /// \return 返回是否在事务中，true为在事务中，false为不在事务中
        virtual bool IsInTransaction() const = 0;

        /// \brief 开启/关闭外键约束
        /// \param enable 是否开启
        /// \return 返回是否成功
        virtual void EnableForeignKeys(bool enable) = 0;

    public:
        virtual ~IFamilyDatabase() = 0 {};
    };


    /// \brief 数据库表接口
    class IFamilyDataTable
    {
    public:
        /// \brief 获取数据表名
        /// \return 返回数据表名
        virtual std::wstring GetTableName() const = 0;

        /// \brief 设置数据表名
        /// \param tableName 数据表名
        virtual void SetTableName(const std::wstring& tableName) = 0;

    public:
        /// \brief 创建数据表列
        /// \return 返回新创建的数据表列指针
        virtual std::shared_ptr<IFamilyDataColumn> NewColumn() = 0;

        /// \brief 添加数据表列
        /// \param newColumn 数据表列
        virtual void AddColumn(const std::shared_ptr<IFamilyDataColumn> newColumn) = 0;

        /// \brief 删除数据表列
        /// \param columnName 数据表列名
        virtual void RemoveColumn(const std::wstring& columnName) = 0;

        /// \brief 获取数据表主键列
        /// \return 数据表主键列指针
        virtual  std::shared_ptr<IFamilyDataColumn> GetPrimaryKey() const = 0;

        /// \brief 设置数据表主键列
        /// \param column 数据表列指针
        virtual void SetPrimaryKey(const std::shared_ptr<IFamilyDataColumn> column) = 0;

    public:
        /// \brief 创建数据表行
        /// \return 返回新创建的数据表行指针
        virtual std::shared_ptr<IFamilyDataRow> NewRow() = 0;

        /// \brief 添加数据表行
        /// \param newRow 数据表行指针
        virtual void AddRow(const std::shared_ptr<IFamilyDataRow> newRow) = 0;

        /// \brief 删除数据表行
        /// \param row 数据表行指针
        virtual void RemoveRow(const std::shared_ptr<IFamilyDataRow> row) = 0;

        /// \brief 移除所有行
        virtual void Clear() = 0;

    public:
        /// \brief 获取数据表列集合
        /// \return 返回数据表列集合指针
        virtual std::shared_ptr<IFamilyDataColumnList> GetColumns() const = 0;

        /// \brief 获取数据表行集合
        /// \return 返回数据表行集合指针
        virtual std::shared_ptr<IFamilyDataRowList> GetRows() const = 0;

        /// \brief 获取满足条件的数据表行集合
        /// \param condition 条件字符串
        /// \return 返回数据表行集合指针
        virtual std::shared_ptr<IFamilyDataRowList> SelectList(const std::wstring& condition) const = 0;

    public:
        virtual ~IFamilyDataTable() = 0 {};
    };


    /// \brief 数据库表列接口
    class IFamilyDataColumn
    {
    public:
        /// \brief 获取列索引
        /// \return 返回列索引
        virtual int GetIndex() const = 0;

    public:
        /// \brief 获取列名称
        /// \return 返回列名称
        virtual std::wstring GetColumnName() const = 0;

        /// \brief 设置列名称
        /// \param columnName 列名称
        virtual void SetColumnName(const std::wstring& columnName) = 0;

        /// \brief 获取数据类型
        /// \return 返回数据类型
        virtual FamilyDataType GetDataType() const = 0;

        /// \brief 设置数据类型
        /// \param dataType 数据类型
        virtual void SetDataType(FamilyDataType dataType) = 0;

        /// \brief 是否为NotNull
        /// \return 返回true此列不可为空，否则此列可为空
        virtual bool IsNotNull() const = 0;

        /// \brief 设置是否为NotNull
        /// \param isNotNull 是否不可为空
        virtual void SetNotNull(bool isNotNull) = 0;

        /// \brief 是否自动递增
        /// \return 返回true此列自动递增，否则此列非自动递增
        virtual bool IsAutoIncrement() const = 0;

        /// \brief 设置是否自动递增
        /// \param isAutoIncrement 是否自动递增
        virtual void SetAutoIncrement(bool isAutoIncrement) = 0;

        /// \brief 是否唯一
        /// \return 返回true此列唯一，否则此列非唯一
        virtual bool IsUnique() const = 0;

        /// \brief 设置是否唯一
        /// \param isUnique 是否唯一
        virtual void SetUnique(bool isUnique) = 0;

    public:
        /// \brief 获取数据表
        /// \return 返回当前列所在的数据表
        virtual std::shared_ptr<IFamilyDataTable> GetTable() const = 0;

    public:
        virtual ~IFamilyDataColumn() = 0 {};
    };


    /// \brief 数据库表行接口
    class IFamilyDataRow
    {
    public:
        /// \brief 获取Item数量
        /// \return 返回Item数量
        virtual int GetCount() const = 0;

    public:
        /// \brief 获取数据（以Int格式）
        /// \param index 列索引
        /// \return 返回数据
        virtual int GetAsInt(int index) const = 0;

        /// \brief 获取数据（以Double格式）
        /// \param index 列索引
        /// \return 返回数据
        virtual double GetAsDouble(int index) const = 0;

        /// \brief 获取数据（以String格式）
        /// \param index 列索引
        /// \return 返回数据
        virtual std::wstring GetAsString(int index) const = 0;

        /// \brief 字段是否为空（以String格式）
        /// \return 返回是否是空
        virtual bool IsNull(int index) const = 0;

        /// \brief 字段值转换为字符串类型
        /// \return 返回值字符串
        virtual std::wstring ToString(int index) const = 0;

        /// \brief 设置数据（以Int格式）
        /// \param index 列索引
        /// \param value 数据
        virtual void SetAsInt(int index, int value) = 0;

        /// \brief 设置数据（以Double格式）
        /// \param index 列索引
        /// \param value 数据
        virtual void SetAsDouble(int index, double value) = 0;

        /// \brief 设置数据（以String格式）
        /// \param index 列索引
        /// \param value 数据
        virtual void SetAsString(int index, const std::wstring& value) = 0;

        // \brief 设置为Null
        virtual void SetNull(int index) = 0;

    public:
        /// \brief 获取数据表
        /// \return 返回当前列所在的数据表
        virtual std::shared_ptr<IFamilyDataTable> GetTable() const = 0;

    public:
        virtual ~IFamilyDataRow() = 0 {};
    };


    /// \brief 数据表视图类
    class IFamilyDataTableList
    {
    public:
        /// \brief 获取集合中的数据表数目
        /// \return 返回数据表数目
        virtual int GetCount() const = 0;

        /// \brief 获取集合中指定索引的数据表
        /// \param index 数据表索引
        /// \return 返回数据表指针
        virtual std::shared_ptr<IFamilyDataTable> GetItem(int index) const = 0;

    public:
        virtual ~IFamilyDataTableList() = 0 {};
    };


    /// \brief 数据表列集合类
    class IFamilyDataColumnList
    {
    public:
        /// \brief 获取集合中的数据表列数目
        /// \return 返回数据表列数目
        virtual int GetCount() const = 0;

        /// \brief 获取集合中指定索引的数据表列
        /// \param index 数据表列索引
        /// \return 返回数据表列指针
        virtual std::shared_ptr<IFamilyDataColumn> GetItem(int index) const = 0;

        /// \brief 查找集合中指定名称的数据表列
        /// \param columnName 数据表列名称
        /// \return 返回数据表列指针
        virtual std::shared_ptr<IFamilyDataColumn> FindColumnByName(const std::wstring& columnName) const = 0;

        /// \brief 获取此集合所在的数据表
        /// \return 返回数据表指针
        virtual std::shared_ptr<IFamilyDataTable> GetTable() const = 0;

    public:
        virtual ~IFamilyDataColumnList() = 0 {};
    };


    /// \brief 数据表行集合类
    class IFamilyDataRowList
    {
    public:
        /// \brief 获取集合中的数据表行数目
        /// \return 返回数据表行数目
        virtual int GetCount() const = 0;

        /// \brief 获取集合中指定索引的数据表行
        /// \param index 数据表行索引
        /// \return 返回数据表行指针
        virtual std::shared_ptr<IFamilyDataRow> GetItem(int index) const = 0;

        /// \brief 获取此集合所在的数据表
        /// \return 返回数据表指针
        virtual std::shared_ptr<IFamilyDataTable> GetTable() const = 0;

    public:
        virtual ~IFamilyDataRowList() = 0 {};
    };


    /// \brief 数据库异常类
    class GM_FAMILY_DATABASE_EXPORT FamilyDbException
    {
    public:
        /// \brief 获取异常信息
        /// \return 返回异常信息
        std::wstring GetMessage() const;

    public:
        FamilyDbException(const std::wstring& message);
        FamilyDbException(const FamilyDbException& other);
        ~FamilyDbException();

    private:
        struct Impl;
        std::shared_ptr<Impl> m_pImpl;
    };
}
